package com.kitwee.serialport.decoder;


import java.io.Serializable;
import java.nio.ByteBuffer;

public abstract class InstructionDecoder implements Serializable {

    public InstructionDecoder() {
        // empty constructor
    }

    /**
     * 给参数返回指定小数点后 a 位的四舍五入
     *
     * @param sourceData 要取舍的原数据
     * @param a          小数点 后的 位数（如：10：小数点后1位；100：小数据后2位以此类推）
     * @return 舍取后的 数据
     */
    protected float getFloatRound(double sourceData, int a) {
        int i = (int) Math.round(sourceData * a);     //小数点后 a 位前移，并四舍五入
        float f2 = (float) (i / (float) a);        //还原小数点后 a 位
        return f2;
    }

    /**
     * 字节转换为浮点
     *
     * @param （至少4个字节）
     * @param
     * @return 返回浮点数据
     */
    protected float byte2float(String src) {
//		return Float.intBitsToFloat(Integer.valueOf(src,16));
        return Float.valueOf(Long.valueOf(src, 16));
    }


    /**
     * 字节转换为浮点
     *
     * @param bSource 字节（至少4个字节）
     * @param index   开始位置
     * @return 返回浮点数据
     */
    protected float byte2float(byte[] bSource, int index) {
        int l;
        l = bSource[index + 0];
        l &= 0xff;
        l |= ((long) bSource[index + 1] << 8);
        l &= 0xffff;
        l |= ((long) bSource[index + 2] << 16);
        l &= 0xffffff;
        l |= ((long) bSource[index + 3] << 24);
        return Float.intBitsToFloat(l);
    }

    /**
     * 将4字节的byte数组转成int值.
     *
     * @param bytes 字节数组
     * @return 整形
     */
    protected final int byteArray2int(byte[] bytes) {
        byte[] a = new byte[4];
        int i = a.length - 1;
        int j = bytes.length - 1;
        for (; i >= 0; i--, j--) {// 从b的尾部(即int值的低位)开始copy数据
            if (j >= 0) {
                a[i] = bytes[j];
            } else {
                a[i] = 0;// 如果b.length不足4,则将高位补0
            }
        }
        int v0 = (a[0] & 0xff) << 24;// &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
        int v1 = (a[1] & 0xff) << 16;
        int v2 = (a[2] & 0xff) << 8;
        int v3 = (a[3] & 0xff);
        return v0 + v1 + v2 + v3;
    }

    /**
     * ASCII码转成Byte
     *
     * @param source
     * @return
     */
    protected byte[] asciiTransformByte(char[] source) {
        int arraySize = source.length / 2;
        if (arraySize < 1) {
            arraySize = 1;
        }
        ByteBuffer decodeBuffer = ByteBuffer.allocate(arraySize);

        // 数据从0开始每次自增2
        for (int i = 0; i < source.length; i++) {
            // 高位字节
            byte b1 = Byte.valueOf(String.valueOf(source[i]), 16);
            if (source.length > i + 1) {
                // 低部字节
                byte b2 = Byte.valueOf(String.valueOf(source[++i]), 16);
                // 高位字节上移一位后+下低部字节，得到原始数据
                decodeBuffer.put((byte) ((b1 << 4) + b2));
            } else {
                decodeBuffer.put((byte) b1);
            }
        }
        // 输出原始数据
        return decodeBuffer.array();
    }

    /**
     * 字节数组转16进制字符串.
     *
     * @param buffer 字节数组
     * @return 16进制字符串
     */
    protected final String byteArray2HexString(byte[] buffer) {

        StringBuffer sb = new StringBuffer(buffer.length * 2);

        for (int i = 0; i < buffer.length; i++) {

            sb.append(Character.forDigit((buffer[i] & 240) >> 4, 16));

            sb.append(Character.forDigit(buffer[i] & 15, 16));

        }

        return sb.toString();

    }


    public abstract Object decode(final byte[] source);

}
